package com.netty.quartz.util;

import com.netty.common.constant.Constants;
import com.netty.common.constant.ScheduleConstants;
import com.netty.common.enums.ExceptionEnum;
import com.netty.common.exception.BizException;
import com.netty.common.util.bean.SpringUtils;
import com.netty.quartz.entity.SysJob;
import com.netty.quartz.entity.SysJobLog;
import com.netty.quartz.service.ISysJobLogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.Objects;

/** 任务执行
 * @author LiuXiaoYu
 * @date 2021/10/16- 9:36
 */
@Slf4j
public abstract class AbstractJob implements Job {
    @Override
    public void execute(JobExecutionContext context) {
        SysJob sysJob= (SysJob) context.getJobDetail().getJobDataMap().get(ScheduleConstants.TASK_PROPERTIES);
        //得到现在的时间
        LocalDateTime beforeExecuteTime = LocalDateTime.now();
        try {
              //由子类重载判断是否并发执行任务
               doExecute(context,sysJob);
               //执行任务要记录日志
               afterExecute(sysJob,beforeExecuteTime,null);
           }catch (Exception e){
            afterExecute(sysJob, beforeExecuteTime,e);
            log.error("任务执行异常,{},{}",e,e.getMessage());
            throw new BizException(ExceptionEnum.ERROR,"任务执行异常");
           }
    }

    /**
     * 任务执行后记录日志
     * @param sysJob 任务信息对象
     * @param beforeExecuteTime 执行任务之前的时间
     * @param e 异常
     */
    protected void afterExecute(SysJob sysJob, LocalDateTime beforeExecuteTime,Exception e){
        final SysJobLog sysJobLog = new SysJobLog();
        sysJobLog.setJobName(sysJob.getJobName());
        sysJobLog.setJobGroup(sysJob.getJobGroup());
        sysJobLog.setInvokeTarget(sysJob.getInvokeTarget());
        sysJobLog.setCreateTime(Date.from(beforeExecuteTime.atZone(ZoneId.systemDefault()).toInstant()));
       // sysJobLog.setStopTime(new Date());
        long startTime = beforeExecuteTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
        sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时：" + (endTime-startTime)+ "毫秒");
        if (Objects.nonNull(e)) {
            sysJobLog.setStatus(Constants.FAIL);
            String errorMsg = StringUtils.substring(e.getMessage(), 0, 2000);
            sysJobLog.setExceptionInfo(errorMsg);
        } else {
            sysJobLog.setStatus(Constants.SUCCESS);
        }
        // 写入数据库当中
        SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog);
    }

    /**
     * 执行方法，由子类重载
     *
     * @param context 工作执行上下文对象
     * @param sysJob 系统计划任务
     */
    protected abstract void doExecute(JobExecutionContext context, SysJob sysJob);
}
